//
// Created by kyle on 25-7-15.
//

#include "util.h"
#include <memory>
#include "FrameBuffer.h"
#include "devinfo.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <stdbool.h>
#include <iostream>
#include <string>
#include <cstdio>
#include <memory>
#include <array>

// 填充矩形
void Util::fb_fill_rect(const std::shared_ptr<FrameBuffer> &fb, int x, int y, int width, int height, unsigned char r,
                        unsigned char g, unsigned char b) {
    for (int i = 0; i < height; i++) {
        // fb_draw_line(fb, x, y + i, x + width, y + i, r, g, b);
    }
}

void Util::fb_write_pixel(const std::shared_ptr<FrameBuffer> &fb, int x, int y, unsigned char r, unsigned char g,
                          unsigned char b) {
}

// 绘制矩形
/*void Util::fb_draw_rect(FrameBuffer *fb, int x, int y, int width, int height, unsigned char r, unsigned char g, unsigned char b) {
    // 绘制四条边
    fb_draw_line(fb, x, y, x + width, y, r, g, b); // 上边
    fb_draw_line(fb, x, y + height, x + width, y + height, r, g, b); // 下边
    fb_draw_line(fb, x, y, x, y + height, r, g, b); // 左边
    fb_draw_line(fb, x + width, y, x + width, y + height, r, g, b); // 右边
}*/

// 执行shell命令并获取输出
std::string Util::exec_command(const std::string &cmd) {
    std::array<char, 128> buffer;
    std::string result;

    // 使用popen创建管道并执行命令
    std::unique_ptr<FILE, decltype(&pclose)> pipe(popen(cmd.c_str(), "r"), pclose);
    if (!pipe) {
        throw std::runtime_error("popen() failed!");
    }

    // 读取命令输出
    while (fgets(buffer.data(), buffer.size(), pipe.get())) {
        result += buffer.data();
    }

    return result;
}

//字符转整形
int Util::stringToIntStoi(const std::string &str) {
    if (str.empty()) {
        throw std::invalid_argument("Empty string");
    }

    try {
        size_t pos = 0;
        int result = std::stoi(str, &pos);

        // 检查是否整个字符串都被转换
        if (pos != str.size()) {
            // 检查是否只是尾部空格
            while (pos < str.size() && std::isspace(static_cast<unsigned char>(str[pos]))) {
                ++pos;
            }
            if (pos != str.size()) {
                throw std::invalid_argument("Non-numeric characters found");
            }
        }

        return result;
    } catch (const std::invalid_argument &) {
        throw std::invalid_argument("Invalid argument for conversion");
    }
    catch (const std::out_of_range &) {
        throw std::out_of_range("Value out of range for int");
    }
}

/**
 * 读取文件内容
 * @param path
 * @return
 */
std::string Util::readFile(std::string_view path) {
    std::ifstream file(path.data());
    if (!file.is_open()) {
        throw std::system_error(errno, std::system_category(), "Failed to open file");
    }

    std::string content;
    std::getline(file, content);
    return content;
}

std::string Util::readFileOrDefault(std::string_view path, std::string_view defaultValue) {
    std::ifstream file(path.data());
    if (!file.is_open()) {
        return std::string(defaultValue);
    }

    std::string content;
    if (!std::getline(file, content)) {
        return std::string(defaultValue);
    }
    return content;
}


// 将UTF-8字符串分割为Unicode字符向量
std::vector<std::string> Util::split_utf8(const std::string &str) {
    std::vector<std::string> chars;
    for (int i = 0; i < str.length();) {
        int len = 1;
        unsigned char c = static_cast<unsigned char>(str[i]);
        if ((c & 0x80) == 0) {
            // 1字节字符 (0xxxxxxx)
            len = 1;
        } else if ((c & 0xE0) == 0xC0) {
            // 2字节字符 (110xxxxx)
            len = 2;
        } else if ((c & 0xF0) == 0xE0) {
            // 3字节字符 (1110xxxx)
            len = 3;
        } else if ((c & 0xF8) == 0xF0) {
            // 4字节字符 (11110xxx)
            len = 4;
        }
        // 检查是否超出字符串范围
        if (i + len > str.length()) {
            len = str.length() - i;
        }
        chars.push_back(str.substr(i, len));
        i += len;
    }
    return chars;
}

TextObject Util::calculateBestFontSize(int screen_width, int screen_height, double font_radio,
                                       const std::string &text) {
    TextObject result;
    result.radio = font_radio;

    // 处理空文本情况
    if (text.empty()) {
        result.width = screen_width;
        result.height = screen_height;
        return result;
    }

    // 分割UTF-8字符串
    std::vector<std::string> chars = split_utf8(text);
    int n = chars.size();

    int best_font_width = screen_width; // 初始化为屏幕宽度

    // 寻找最佳字体大小
    for (int fw = screen_width; fw > 0; --fw) {
        int fh = static_cast<int>(fw * font_radio);
        if (fh < 1) fh = 1; // 确保高度至少为1像素

        int hchars = 1.0 * screen_width / fw;
        int vchars = 1.0 * screen_height / fh;

        // 检查是否能够容纳所有字符
        if (hchars * vchars >= n) {
            best_font_width = fw;
            break;
        }
    }

    // 设置结果
    result.width = best_font_width;
    result.height = static_cast<int>(best_font_width * font_radio);
    if (result.height < 1) result.height = 1;

    return result;
}
